import 'package:built_collection/built_collection.dart';
import 'package:backend.core/core/domain/entities/api/google_play/api_google_play_purchased_subscription.dart';
import 'package:equatable/equatable.dart';
import 'package:backend.purchases/infrastructure/dtos/api/api_time_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_item_acknowledgement_status_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_item_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_subscription_cancellation_info_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_subscription_cancellation_info_dto_factory.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_subscription_pause_info_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_subscription_price_change_status_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_subscription_status_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/google_play/api_google_play_purchased_subscription_transaction_dto.dart';

const kApiGooglePlayPurchasedSubscriptionStartTimeKey = 'start_time';
const kApiGooglePlayPurchasedSubscriptionAutoRenewalEnabledKey = 'auto_renewal_enabled';
const kApiGooglePlayPurchasedSubscriptionStatusKey = 'status';
const kApiGooglePlayPurchasedSubscriptionExpirationTimeKey = 'expiration_time';
const kApiGooglePlayPurchasedSubscriptionPriceChangeStatusKey = 'price_change_status';
const kApiGooglePlayPurchasedSubscriptionCancellationInfoKey = 'cancellation_info';
const kApiGooglePlayPurchasedSubscriptionPauseInfoKey = 'pause_info';
const kApiGooglePlayPurchasedSubscriptionTransactionsKey = 'transactions';

const kApiGooglePlayPurchasedSubscriptionTypeValue = 'purchased_subscription';

class ApiGooglePlayPurchasedSubscriptionDto extends Equatable
    implements ApiGooglePlayPurchasedItemDto {
  const ApiGooglePlayPurchasedSubscriptionDto._internal({
    required this.purchaseItemSku,
    required this.purchaseToken,
    required this.test,
    required this.startTimeDto,
    required this.autoRenewalEnabled,
    required this.statusDto,
    required this.expirationTimeDto,
    required this.acknowledgementStatusDto,
    required this.priceChangeStatusDto,
    required this.cancellationInfoDto,
    required this.pauseInfoDto,
    required this.transactionDtos,
  });

  @override
  final String purchaseItemSku;

  @override
  final String purchaseToken;

  @override
  final bool test;

  @override
  final ApiGooglePlayPurchasedItemAcknowledgementStatusDto acknowledgementStatusDto;

  final ApiTimeDto startTimeDto;
  final bool autoRenewalEnabled;
  final ApiGooglePlayPurchasedSubscriptionStatusDto statusDto;
  final ApiTimeDto? expirationTimeDto;
  final ApiGooglePlayPurchasedSubscriptionPriceChangeStatusDto priceChangeStatusDto;
  final ApiGooglePlayPurchasedSubscriptionCancellationInfoDto? cancellationInfoDto;
  final ApiGooglePlayPurchasedSubscriptionPauseInfoDto? pauseInfoDto;
  final BuiltList<ApiGooglePlayPurchasedSubscriptionTransactionDto> transactionDtos;

  @override
  String get type => kApiGooglePlayPurchasedSubscriptionTypeValue;

  @override
  List<Object?> get props {
    return [
      purchaseItemSku,
      purchaseToken,
      test,
      startTimeDto,
      autoRenewalEnabled,
      statusDto,
      expirationTimeDto,
      acknowledgementStatusDto,
      priceChangeStatusDto,
      cancellationInfoDto,
      pauseInfoDto,
      transactionDtos,
    ];
  }

  factory ApiGooglePlayPurchasedSubscriptionDto.fromEntity(
      ApiGooglePlayPurchasedSubscription purchasedSubscription) {
    final startTimeDto = ApiTimeDto.fromEntity(purchasedSubscription.startTime);

    final statusDto =
        ApiGooglePlayPurchasedSubscriptionStatusDto.fromEntity(purchasedSubscription.status);

    ApiTimeDto? expirationTimeDto;

    if (purchasedSubscription.expirationTime != null) {
      expirationTimeDto = ApiTimeDto.fromEntity(purchasedSubscription.expirationTime!);
    }

    final priceChangeStatusDto = ApiGooglePlayPurchasedSubscriptionPriceChangeStatusDto.fromEntity(
        purchasedSubscription.priceChangeStatus);

    ApiGooglePlayPurchasedSubscriptionCancellationInfoDto? cancellationInfoDto;

    if (purchasedSubscription.cancellationInfo != null) {
      cancellationInfoDto = ApiGooglePlayPurchasedSubscriptionCancellationInfoDtoFactory()
          .fromEntity(purchasedSubscription.cancellationInfo!);
    }

    ApiGooglePlayPurchasedSubscriptionPauseInfoDto? pauseInfoDto;

    if (purchasedSubscription.pauseInfo != null) {
      pauseInfoDto = ApiGooglePlayPurchasedSubscriptionPauseInfoDto.fromEntity(
          purchasedSubscription.pauseInfo!);
    }

    final transactionDtos = purchasedSubscription.transactions.map((transaction) {
      return ApiGooglePlayPurchasedSubscriptionTransactionDto.fromEntity(transaction);
    }).toBuiltList();

    final acknowledgementStatusDto = ApiGooglePlayPurchasedItemAcknowledgementStatusDto.fromEntity(
        purchasedSubscription.acknowledgementStatus);

    return ApiGooglePlayPurchasedSubscriptionDto._internal(
      purchaseItemSku: purchasedSubscription.purchaseItemSku,
      purchaseToken: purchasedSubscription.purchaseToken,
      test: purchasedSubscription.test,
      startTimeDto: startTimeDto,
      statusDto: statusDto,
      expirationTimeDto: expirationTimeDto,
      autoRenewalEnabled: purchasedSubscription.autoRenewalEnabled,
      acknowledgementStatusDto: acknowledgementStatusDto,
      priceChangeStatusDto: priceChangeStatusDto,
      cancellationInfoDto: cancellationInfoDto,
      pauseInfoDto: pauseInfoDto,
      transactionDtos: transactionDtos,
    );
  }

  @override
  Map<String, dynamic> toJson() {
    final transactionJsons = transactionDtos.map((transactionDto) {
      return transactionDto.toJson();
    }).toList();

    return {
      kApiGooglePlayPurchasedItemTypeKey: type,
      kApiGooglePlayPurchasedItemPurchaseItemSkuKey: purchaseItemSku,
      kApiGooglePlayPurchasedItemPurchaseTokenKey: purchaseToken,
      kApiGooglePlayPurchasedItemTestKey: test,
      kApiGooglePlayPurchasedItemAcknowledgementStatusKey: acknowledgementStatusDto.toString(),
      kApiGooglePlayPurchasedSubscriptionStartTimeKey: startTimeDto.toString(),
      kApiGooglePlayPurchasedSubscriptionAutoRenewalEnabledKey: autoRenewalEnabled,
      kApiGooglePlayPurchasedSubscriptionStatusKey: statusDto.toString(),
      kApiGooglePlayPurchasedSubscriptionExpirationTimeKey: expirationTimeDto?.toString(),
      kApiGooglePlayPurchasedSubscriptionPriceChangeStatusKey: priceChangeStatusDto.toString(),
      kApiGooglePlayPurchasedSubscriptionCancellationInfoKey: cancellationInfoDto?.toJson(),
      kApiGooglePlayPurchasedSubscriptionPauseInfoKey: pauseInfoDto?.toJson(),
      kApiGooglePlayPurchasedSubscriptionTransactionsKey: transactionJsons,
    };
  }
}
